/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "i2c.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"

#include "epd_2in9.h"
#include "epd_ui.h"
#include "cardDataTypes.h"
#include "gt30l32.h"
#include "utf8_gbk.h"
#include "LoRa.h"
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for SysLED_Task */
osThreadId_t SysLED_TaskHandle;
const osThreadAttr_t SysLED_Task_attributes = {
  .name = "SysLED_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for UI_Task */
osThreadId_t UI_TaskHandle;
const osThreadAttr_t UI_Task_attributes = {
  .name = "UI_Task",
  .stack_size = 512 * 4,
  .priority = (osPriority_t) osPriorityLow1,
};
/* Definitions for LoRa_Task */
osThreadId_t LoRa_TaskHandle;
const osThreadAttr_t LoRa_Task_attributes = {
  .name = "LoRa_Task",
  .stack_size = 256 * 4,
  .priority = (osPriority_t) osPriorityAboveNormal,
};
/* Definitions for Key_Task */
osThreadId_t Key_TaskHandle;
const osThreadAttr_t Key_Task_attributes = {
  .name = "Key_Task",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityHigh,
};
/* Definitions for LoRaReceive_Queue */
osMessageQueueId_t LoRaReceive_QueueHandle;
const osMessageQueueAttr_t LoRaReceive_Queue_attributes = {
  .name = "LoRaReceive_Queue"
};
/* Definitions for LoRaSend_Queue */
osMessageQueueId_t LoRaSend_QueueHandle;
const osMessageQueueAttr_t LoRaSend_Queue_attributes = {
  .name = "LoRaSend_Queue"
};
/* Definitions for KeyValue_Queue */
osMessageQueueId_t KeyValue_QueueHandle;
const osMessageQueueAttr_t KeyValue_Queue_attributes = {
  .name = "KeyValue_Queue"
};
/* Definitions for SPI_Mutex */
osMutexId_t SPI_MutexHandle;
const osMutexAttr_t SPI_Mutex_attributes = {
  .name = "SPI_Mutex"
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void LED_Work(void *argument);
void UI_Work(void *argument);
void LoRa_Work(void *argument);
void Key_work(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */
  /* Create the mutex(es) */
  /* creation of SPI_Mutex */
  SPI_MutexHandle = osMutexNew(&SPI_Mutex_attributes);

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the queue(s) */
  /* creation of LoRaReceive_Queue */
  LoRaReceive_QueueHandle = osMessageQueueNew (8, 256, &LoRaReceive_Queue_attributes);

  /* creation of LoRaSend_Queue */
  LoRaSend_QueueHandle = osMessageQueueNew (8, 256, &LoRaSend_Queue_attributes);

  /* creation of KeyValue_Queue */
  KeyValue_QueueHandle = osMessageQueueNew (8, sizeof(uint8_t), &KeyValue_Queue_attributes);

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of SysLED_Task */
  SysLED_TaskHandle = osThreadNew(LED_Work, NULL, &SysLED_Task_attributes);

  /* creation of UI_Task */
  UI_TaskHandle = osThreadNew(UI_Work, NULL, &UI_Task_attributes);

  /* creation of LoRa_Task */
  LoRa_TaskHandle = osThreadNew(LoRa_Work, NULL, &LoRa_Task_attributes);

  /* creation of Key_Task */
  Key_TaskHandle = osThreadNew(Key_work, NULL, &Key_Task_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_LED_Work */
/**
  * @brief  Function implementing the SysLED_Task thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_LED_Work */
void LED_Work(void *argument)
{
  /* USER CODE BEGIN LED_Work */
  /* Infinite loop */
  for(;;)
  {
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
    osDelay(50);
    HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
    osDelay(450);
  }
  /* USER CODE END LED_Work */
}

/* USER CODE BEGIN Header_UI_Work */
/**
* @brief Function implementing the UI_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_UI_Work */
void UI_Work(void *argument)
{
  /* USER CODE BEGIN UI_Work */
  EPD_Init(EPD_PART);
  EPD_SetFullBuffer(0xff);
  ClassScheduleTypeDef myClassInfo;
  memset(&myClassInfo, 0, sizeof(myClassInfo));
  myClassInfo.classNum = 8;
  strcpy(myClassInfo.date, "12月12号");
  strcpy(myClassInfo.week, "星期天");
  strcpy(myClassInfo.classInfo[0].time, "8:00");
  strcpy(myClassInfo.classInfo[0].classRoomName, "泉教E205");
  strcpy(myClassInfo.classInfo[0].CourseName, "物联网通信技术");
  strcpy(myClassInfo.classInfo[1].time, "11:00");
  strcpy(myClassInfo.classInfo[1].classRoomName, "信息楼808");
  strcpy(myClassInfo.classInfo[1].CourseName, "物联网通信技术实验");
  strcpy(myClassInfo.classInfo[2].time, "14:00");
  strcpy(myClassInfo.classInfo[2].classRoomName, "东操场");
  strcpy(myClassInfo.classInfo[2].CourseName, "足球");
  strcpy(myClassInfo.classInfo[3].time, "16:30");
  strcpy(myClassInfo.classInfo[3].classRoomName, "学术报告厅");
  strcpy(myClassInfo.classInfo[3].CourseName, "遥感通信技术讲座");
  UI_DisplayClassSchedule(&myClassInfo);
//  EPD_Refresh();
  /* Infinite loop */
  for(;;)
  {

    osMutexAcquire(SPI_MutexHandle, osWaitForever);
    EPD_Refresh();
    osMutexRelease(SPI_MutexHandle);

    osDelay(100);
  }
  /* USER CODE END UI_Work */
}

/* USER CODE BEGIN Header_LoRa_Work */
/**
* @brief Function implementing the LoRa_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LoRa_Work */
void LoRa_Work(void *argument)
{
  /* USER CODE BEGIN LoRa_Work */
  LoRaAttr_t LoRa_Attributes;
  memset(&LoRa_Attributes, 0, sizeof(LoRa_Attributes));
  LoRa_Attributes.frequency = 460.500e6;
  LoRa_Attributes.signalBandwidth = 250e6;
  LoRa_Attributes.spreadingFactor = 11;
  LoRa_Attributes.codingRate = 8;
  LoRa_Attributes.txPower = 17;
  LoRa_Attributes.syncCode = 0xaa;
  osMutexAcquire(SPI_MutexHandle, osWaitForever);
  LoRa_Init(&LoRa_Attributes);
  osMutexRelease(SPI_MutexHandle);
  /* Infinite loop */
  for(;;)
  {
    osMutexAcquire(SPI_MutexHandle, osWaitForever);
    LoRa_BeginPacket(0);
    LoRa_WriteFifoBytes((uint8_t*)"Hello", 6);
    LoRa_EndPacket();
    osMutexRelease(SPI_MutexHandle);
    osDelay(2000);
  }
  /* USER CODE END LoRa_Work */
}

/* USER CODE BEGIN Header_Key_work */
/**
* @brief Function implementing the Key_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Key_work */
void Key_work(void *argument)
{
  /* USER CODE BEGIN Key_work */
  uint8_t keyVal;
  /* Infinite loop */
  for(;;)
  {
    if(osMessageQueueGetSpace(KeyValue_QueueHandle) > 0)
    {
      if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
      {
        keyVal = 0;
        osMessageQueuePut(KeyValue_QueueHandle, &keyVal, 0, 0);
      }
      else if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)
      {
        keyVal = 1;
        osMessageQueuePut(KeyValue_QueueHandle, &keyVal, 0, 0);
      }
      else if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)
      {
        keyVal = 2;
        osMessageQueuePut(KeyValue_QueueHandle, &keyVal, 0, 0);
      }
      else if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)
      {
        keyVal = 3;
        osMessageQueuePut(KeyValue_QueueHandle, &keyVal, 0, 0);
      }
    }
    osDelay(100);
  }
  /* USER CODE END Key_work */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
